﻿using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// BindSimulateBehaviour收集器
/// </summary>
[AddComponentMenu("ESF/BindSimulateBehaviour/BindSimulateBehaviour_Collect")]
[DisallowMultipleComponent]
public sealed class BindSimulateBehaviour_Collect : MonoBehaviour
{
#if UNITY_EDITOR
    /// <summary>
    /// 绑定的GameObject数量
    /// </summary>
    [SerializeField]
    int mEditorBindGameObjectCount = 0;
    /// <summary>
    /// 绑定的ISimulateBehaviour数量
    /// </summary>
    [SerializeField]
    int mEditorBindISimulateBehaviourCount = 0;
    /// <summary>
    /// 绑定的ISimulateBehaviour名称
    /// </summary>
    [SerializeField]
    UnityDictionary<string, int> mEditorBindClassNames;
#endif
    /// <summary>
    /// 已绑定的事件组件
    /// Key:BindEventKey
    /// Value:IBindSimulateBehaviour
    /// </summary>
    Dictionary<int, IBindSimulateBehaviour> mBindSimulateBehaviourMaping = new Dictionary<int, IBindSimulateBehaviour>();
    /// <summary>
    /// 已经有绑定的组件
    /// Key:GameObject.GetInstanceID
    /// Value:[Key:simulateGlobalId,Value:ISimulateBehaviour]
    /// </summary>
    Dictionary<int, Dictionary<long,ISimulateBehaviour>> mISimulateBehaviourMaping = new Dictionary<int, Dictionary<long, ISimulateBehaviour>>();
    /// <summary>
    ///绑定指定事件的事件组件
    /// </summary>
    /// <param name="_bindEvtKey">事件Key</param>
    /// <param name="_bindEvtType">绑定事件组件类型</param>
    /// <param name="_bindISB">绑定对象</param>
    public void BindSimulateBehaviour(int _bindEvtKey, Type _bindEvtType, ISimulateBehaviour _bindISB)
    {
        Component com = gameObject.GetOrAddComponent(_bindEvtType);
        IBindSimulateBehaviour bsb = com as IBindSimulateBehaviour;
        bsb.BindSimulateBehaviour(_bindISB);
        mBindSimulateBehaviourMaping[_bindEvtKey] = bsb;
        Dictionary<long, ISimulateBehaviour> isbs = null;
        if (!mISimulateBehaviourMaping.TryGetValue(_bindISB.bindGameObjectInstanceId,out isbs))
        {
            isbs = new Dictionary<long, ISimulateBehaviour>();
            mISimulateBehaviourMaping.Add(_bindISB.bindGameObjectInstanceId, isbs);
        }
        if (!isbs.ContainsKey(_bindISB.simulateGlobalId))
        {
            isbs.Add(_bindISB.simulateGlobalId,_bindISB);
        }
#if UNITY_EDITOR
        OnStatisticsBindInfo();
#endif
    }

    /// <summary>
    /// 获得指定事件的绑定组件
    /// </summary>
    /// <param name="_bindEvtKey">事件Key</param>
    /// <returns>绑定组件</returns>
    public IBindSimulateBehaviour GetBindSimulateBehaviour(int _bindEvtKey)
    {
        IBindSimulateBehaviour result = null;
        mBindSimulateBehaviourMaping.TryGetValue(_bindEvtKey, out result);
        return result;
    }

    /// <summary>
    /// 获得指定GameObject的绑定脚本
    /// </summary>
    /// <param name="_gameObject">GameObject</param>
    /// <returns>GameObject的绑定脚本</returns>
    public Dictionary<long, ISimulateBehaviour> GetSimulateBehaviour(GameObject _gameObject)
    {
        Dictionary<long, ISimulateBehaviour> result = null;
        mISimulateBehaviourMaping.TryGetValue(_gameObject.GetInstanceID(), out result);
        return result;
    }

    /// <summary>
    /// 移除ISimulateBehaviour对象
    /// </summary>
    /// <param name="_bindISB">绑定的ISimulateBehaviour对象</param>
    public void RemoveBindEventBehaviour(ISimulateBehaviour _bindISB)
    {
        if (mBindSimulateBehaviourMaping != null)
        {
            foreach (var key in mBindSimulateBehaviourMaping)
            {
                key.Value.RemoveBindEventBehaviour(_bindISB);
            }
            mBindSimulateBehaviourMaping.Clear();
        }
        if (mISimulateBehaviourMaping != null)
        {
            Dictionary<long, ISimulateBehaviour> isbs = null;
            if (mISimulateBehaviourMaping.TryGetValue(_bindISB.bindGameObjectInstanceId, out isbs))
            {
                isbs.Remove(_bindISB.simulateGlobalId);
            }
        }        
#if UNITY_EDITOR
        OnStatisticsBindInfo();
#endif
    }

    /// <summary>
    /// 销毁
    /// </summary>
    private void OnDestroy()
    {
        mBindSimulateBehaviourMaping.Clear();
        mBindSimulateBehaviourMaping = null;
        mISimulateBehaviourMaping.Clear();
        mISimulateBehaviourMaping = null;
    }

#if UNITY_EDITOR
    /// <summary>
    /// 统计绑定信息
    /// </summary>
    void OnStatisticsBindInfo()
    {
        mEditorBindGameObjectCount = 0;
        mEditorBindISimulateBehaviourCount = 0;
        mEditorBindClassNames = new UnityDictionary<string, int>();
        if (mISimulateBehaviourMaping != null)
        {
            mEditorBindGameObjectCount = mISimulateBehaviourMaping.Count;
            mEditorBindISimulateBehaviourCount = 0;
            foreach (var key in mISimulateBehaviourMaping)
            {
                mEditorBindISimulateBehaviourCount += key.Value.Count;
                foreach (var cls in key.Value)
                {
                    string name = cls.Value.ToString();
                    if (!mEditorBindClassNames.ContainsKey(name))
                    {
                        mEditorBindClassNames[name] = 0;
                    }
                    mEditorBindClassNames[name]++;
                }                
            }
        }
    }
#endif
}
